﻿using System;
using System.Drawing.Printing;
using System.Runtime.Serialization;
using ApplicationLibrary.ExtendedControls;

namespace ApplicationLibrary.Preferences
{
    public partial class PrinterPreferencePanel : PrinterPreferencePanelNoVis
    {
        private EnumsManager<Orientation> LetterOrientationTypes = null;
        private EnumsManager<Orientation> EnvelopeOrientationTypes = null;
        private ComboBoxManager LetterSourceType = null;
        private ComboBoxManager EnvelopeSourceType = null;
        private ComboBoxManager LetterSizeType = null;
        private ComboBoxManager EnvelopeSizeType = null;

        public PrinterPreferencePanel(string appName)
            : base(appName, new Type[] { typeof(PrinterData) })
        {
            InitializeComponent();
            ButtonText = Properties.Resources.T_Printer;
            ButtonImage = Properties.Resources.Printer;

            LetterOrientationTypes = new EnumsManager<Orientation>(cbbLetterOrientation, Properties.Resources.ResourceManager);
            EnvelopeOrientationTypes = new EnumsManager<Orientation>(cbbEnvelopeOrientation, Properties.Resources.ResourceManager);
            LetterSourceType = new ComboBoxManager(cbbLetterSource);
            EnvelopeSourceType = new ComboBoxManager(cbbEnvelopeSource);
            LetterSizeType = new ComboBoxManager(cbbLetterSize);
            EnvelopeSizeType = new ComboBoxManager(cbbEnvelopeSize);
            LetterSourceType.CreateList<int>();
            EnvelopeSourceType.CreateList<int>();
            LetterSizeType.CreateList<int>();
            EnvelopeSizeType.CreateList<int>();

            foreach (String printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
            {
                cbbLetterPrinters.Items.Add(printer.ToString());
                cbbEnvelopePrinters.Items.Add(printer.ToString());
            }
            AddLetterCharacteristics();
            AddEnvelopeCharacteristics();
        }

        public PrinterPreferencePanel()
        {
            InitializeComponent();
        }

        protected override void OnBindData()
        {
            BindControl(cbbLetterPrinters, "Letter.PrinterName");
            BindControl(nudLetterCopies, "Letter.NumPage", "Value");
            BindControl(cbbLetterOrientation, "Letter.Orientation", "SelectedValue");
            BindControl(cbbLetterSource, "Letter.Source", "SelectedValue");
            BindControl(cbbLetterSize, "Letter.Size", "SelectedValue");
            BindControl(ckbLetterCollate, "Letter.Collate", "Checked");

            BindControl(cbbEnvelopePrinters, "Envelope.PrinterName");
            BindControl(nudEnvelopeCopies, "Envelope.NumPage", "Value");
            BindControl(cbbEnvelopeOrientation, "Envelope.Orientation", "SelectedValue");
            BindControl(cbbEnvelopeSource, "Envelope.Source", "SelectedValue");
            BindControl(cbbEnvelopeSize, "Envelope.Size", "SelectedValue");
            BindControl(ckbEnvelopeCollate, "Envelope.Collate", "Checked");
        }

        protected override void OnPrepareAuxData()
        {
        }

        protected override bool OnBeforeAddNew()
        {
            Preferences.Letter.NumPage = 1;
            Preferences.Envelope.NumPage = 1;
            Preferences.Envelope.Orientation = 0;
            Preferences.Letter.Orientation = 1;
            return true;
        }

        protected override void OnValidateControl()
        {
            cbbLetterPrinters.Focus();
        }

        private void cbbLetterPrinters_SelectedIndexChanged(object sender, EventArgs e)
        {
            AddLetterCharacteristics();
        }

        private void cbbEnvelopePrinters_SelectedIndexChanged(object sender, EventArgs e)
        {
            AddEnvelopeCharacteristics();
        }

        private void AddLetterCharacteristics()
        {
            if (cbbLetterPrinters.Items.Count == 0 || cbbLetterPrinters.Text == "")
                return;

            PrinterSettings ps = new PrinterSettings();
            ps.PrinterName = cbbLetterPrinters.Text;
            if (ps.LandscapeAngle > 0)
                cbbLetterOrientation.Enabled = ps.LandscapeAngle > 0;

            LetterSourceType.Clear<int>();
            foreach (PaperSource pps in ps.PaperSources)
                LetterSourceType.AddValue(pps.RawKind, pps.SourceName);

            LetterSourceType.Refresh();

            LetterSizeType.Clear<int>();
            foreach (PaperSize pps in ps.PaperSizes)
                LetterSizeType.AddValue(pps.RawKind, pps.PaperName);

            LetterSizeType.Refresh();
        }

        private void AddEnvelopeCharacteristics()
        {
            if (cbbEnvelopePrinters.Items.Count == 0 || cbbEnvelopePrinters.Text == "")
                return;

            PrinterSettings ps = new PrinterSettings();
            ps.PrinterName = cbbEnvelopePrinters.Text;
            if (ps.LandscapeAngle > 0)
                cbbEnvelopeOrientation.Enabled = ps.LandscapeAngle > 0;

            EnvelopeSourceType.Clear<int>();
            foreach (PaperSource pps in ps.PaperSources)
                EnvelopeSourceType.AddValue(pps.RawKind, pps.SourceName);

            EnvelopeSourceType.Refresh();

            EnvelopeSizeType.Clear<int>();
            foreach (PaperSize pps in ps.PaperSizes)
                EnvelopeSizeType.AddValue(pps.RawKind, pps.PaperName);

            EnvelopeSizeType.Refresh();
        }

        private void ckbLetterCollate_CheckedChanged(object sender, EventArgs e)
        {
            ckbLetterCollate.Text = ckbLetterCollate.Checked
                                ? "1,2 1,2"
                                : "1,1 2,2";
        }

        private void ckbEnvelopeCollate_CheckedChanged(object sender, EventArgs e)
        {
            ckbEnvelopeCollate.Text = ckbEnvelopeCollate.Checked
                                           ? "1,2 1,2"
                                           : "1,1 2,2";
        }
    }

    #region PrinterPreferencePanelNoVis

    public partial class PrinterPreferencePanelNoVis : ApplicationLibrary.Preferences.GenericPreferencePanel<PrinterPref>
    {
        public PrinterPreferencePanelNoVis(string appName, Type[] types)
            : base(appName, types)
        {
        }

        public PrinterPreferencePanelNoVis()
        {
        }
    }

    #endregion

    [DataContract]
    public class PrinterPref
    {
        [DataMember]
        public PrinterData Letter { get; set; }

        [DataMember]
        public PrinterData Envelope { get; set; }

        public PrinterPref()
        {
            System.Drawing.Printing.PrinterSettings oPS = new System.Drawing.Printing.PrinterSettings();
            Letter = new PrinterData();
            Letter.PrinterName = oPS.PrinterName;
            Letter.NumPage = oPS.Copies;
            Letter.Orientation = oPS.DefaultPageSettings.Landscape
                                    ? (int)Orientation.Landscape
                                    : (int)Orientation.Portrait;

            Envelope = new PrinterData();
            Envelope.PrinterName = oPS.PrinterName;
            Envelope.NumPage = oPS.Copies;
            Envelope.Orientation = oPS.DefaultPageSettings.Landscape
                                    ? (int)Orientation.Landscape
                                    : (int)Orientation.Portrait;
        }
    }

    [DataContract]
    public sealed class PrinterData
    {
        [DataMember]
        public string PrinterName { get; set; }

        [DataMember]
        public int NumPage { get; set; }

        [DataMember]
        public int Orientation { get; set; }

        [DataMember]
        public int Source { get; set; }

        [DataMember]
        public int Size { get; set; }

        [DataMember]
        public bool Collate { get; set; }
    }

    public class PrinterPreferencesManager : PreferencesManager<PrinterPref>
    {
        public PrinterPreferencesManager(string application)
            : base(application, new Type[] { typeof(PrinterData) })
        {
        }
    }
}